--
-- Constant: Report Level None
--
CattleProd_REPORT_LEVEL_NONE = 0;

--
-- Constant: Report Level Low
--
CattleProd_REPORT_LEVEL_LOW = 1;

--
-- Constant: Report Level Medium
--
CattleProd_REPORT_LEVEL_MEDIUM = 2;

--
-- Constant: Report Level High
--
CattleProd_REPORT_LEVEL_HIGH = 3;

--
-- Faction: Horde
--
CattleProd_FACTION_HORDE = "Horde";

--
-- Faction: Alliance
--
CattleProd_FACTION_ALLIANCE = "Alliance";

--
-- OnLoad function.
--
-- * Announce Load
-- * Setup Defaults
-- * Register Slash Commands
--
function CattleProd_OnLoad()
	CattleProd_Message("CattleProd Loading");

	-- register slash commands
	CattleProd_RegisterSlashCommands();

	-- start timer library
	CattleProd_Core:SetScript("OnUpdate", CattleProdTimer_OnUpdate);
end

--
-- Current Zone
--
-- use GetRealZoneText()
--
CattleProd_CurrentZone = nil;

--
-- World Map Update Event Handler.
--
-- * Update current zone
--
function CattleProd_WorldMapUpdate()
	local realZoneText = GetRealZoneText();
    
	CattleProd_UpdateZone(realZoneText);
end

--
-- Update Zone.
--
-- * Update CattleProd_CurrentZone
-- * If new zone, check if it is a battleground and start monitor
--   if it is, otherwise stop monitor.
--
function CattleProd_UpdateZone(zoneName)
	if (zoneName == CattleProd_CurrentZone)
	then
		-- no zone change
		return;
	else
		-- clear old player states data
		CattleProd_StateStop();
		CattleProd_ClearPlayersStates();
		CattleProd_TearDownState();
	end

	-- update current zone
	CattleProd_CurrentZone = zoneName;

	-- check if we should auto start/stop monitor
	local autoStartMonitor = CattleProd_GetSetting(CattleProd_AUTO_START_MONITOR);

	if (autoStartMonitor)
	then
		if (CattleProd_LocaleEqual(CattleProd_ZONE_ALTERAC_VALLEY, CattleProd_CurrentZone))
		then
			CattleProd_ReportKnownLeechesTimer();
			CattleProd_SetupAlteracValley();
			CattleProd_StateStart();
			CattleProd_MonitorStart();
		elseif (CattleProd_LocaleEqual(CattleProd_ZONE_ARATHI_BASIN, CattleProd_CurrentZone))
		then
			CattleProd_ReportKnownLeechesTimer();
			CattleProd_ArathiBasinSetup();
			CattleProd_StateStart();
			CattleProd_MonitorStart();
		elseif (CattleProd_LocaleEqual(CattleProd_ZONE_EYE_OF_THE_STORM, CattleProd_CurrentZone))
		then
			CattleProd_ReportKnownLeechesTimer();
			CattleProd_EyeOfTheStormSetup();
			CattleProd_StateStart();
			CattleProd_MonitorStart();
		elseif (CattleProd_LocaleEqual(CattleProd_ZONE_WARSONG_GULCH, CattleProd_CurrentZone))
		then
			CattleProd_ReportKnownLeechesTimer();
			CattleProd_StateStart();
			-- do not auto start until battleground
			-- specific code is implemented
			--CattleProd_MonitorStart();
		else
			CattleProd_MonitorStop();
		end
	end
end

--
-- Player is in battleground.
--
-- return Boolean
--
function CattleProd_InBattleground()
	if (CattleProd_CurrentZone == nil)
	then
		return false;
	elseif (CattleProd_LocaleEqual(CattleProd_ZONE_ALTERAC_VALLEY, CattleProd_CurrentZone))
	then
		return true;
	elseif (CattleProd_LocaleEqual(CattleProd_ZONE_ARATHI_BASIN, CattleProd_CurrentZone))
	then
		return true;
	elseif (CattleProd_LocaleEqual(CattleProd_ZONE_EYE_OF_THE_STORM, CattleProd_CurrentZone))
	then
		return true;
	elseif (CattleProd_LocaleEqual(CattleProd_ZONE_WARSONG_GULCH, CattleProd_CurrentZone))
	then
		return true;
	else
		return false;
	end
end

--
-- Report Known Leeches Sate Key
--
CattleProd_REPORT_KNOWN_LEECHES_TIMER_KEY = "reportKnownLeeches";

--
-- Setip timer to report known leeches.
--
function CattleProd_ReportKnownLeechesTimer()
	-- add timer to report known leeches
	CattleProdTimer_AddListener(
		CattleProd_REPORT_KNOWN_LEECHES_TIMER_KEY, 90, 1, CattleProd_ReportKnownLeeches);
end

--
-- State Timer Key
--
CattleProd_STATE_TIMER_KEY = "state";

--
-- Start state timer.
--
function CattleProd_StateStart()
	local interval = CattleProd_GetCalculatePlayerStateInterval();

	-- add timer to start accumulating state
	CattleProdTimer_AddListener(
		CattleProd_STATE_TIMER_KEY, interval, -1, CattleProd_RecordState);
end

--
-- Stop state timer.
--
function CattleProd_StateStop()
	CattleProdTimer_RemoveListener(CattleProd_STATE_TIMER_KEY);
end

--
-- Register UPDATE_BATTLEFIELD_SCORE event and request battlefield
-- score data.  This will cause the listener to update the player
-- state data.
--
function CattleProd_RecordState()
	if (CattleProd_InBattleground())
	then
		CattleProd_Core:RegisterEvent("UPDATE_BATTLEFIELD_SCORE");
	
		-- update score information
		SetBattlefieldScoreFaction(-1);
		RequestBattlefieldScoreData();
	end
end

--
-- Unregister the UPDATE_BATTLEFIELD_SCORE event.  Calculate the players
-- state.
--
function CattleProd_UpdateBattleFieldScore()
	this:UnregisterEvent("UPDATE_BATTLEFIELD_SCORE");
	CattleProd_CalculatePlayersState();
end

--
-- Register slash commands
--
-- * /cpconf
-- * /cpherd
-- * /cptest
--
function CattleProd_RegisterSlashCommands()
	-- /cpconf
	SLASH_CATTLEPROD_CONFIGURE1 = CattleProd_LocaleString(CattleProd_COMMAND_CPCONF);
	SlashCmdList["CATTLEPROD_CONFIGURE"] = CattleProd_Configure;
	DEFAULT_CHAT_FRAME:AddMessage(
		"CattleProd Registered " .. SLASH_CATTLEPROD_CONFIGURE1);

	-- /cpherd
	SLASH_CATTLEPROD_HERD1 = CattleProd_LocaleString(CattleProd_COMMAND_CPHERD);
	SlashCmdList["CATTLEPROD_HERD"] = CattleProd_Main;
	DEFAULT_CHAT_FRAME:AddMessage(
		"CattleProd Registered " .. SLASH_CATTLEPROD_HERD1);

	-- /cpdefend
	SLASH_CATTLEPROD_DEFEND1 = CattleProd_LocaleString(CattleProd_COMMAND_CPDEFEND);
	SlashCmdList["CATTLEPROD_DEFEND"] = CattleProd_Defend;
	DEFAULT_CHAT_FRAME:AddMessage(
		"CattleProd Registered " .. SLASH_CATTLEPROD_DEFEND1);

	-- /cptest
	SLASH_CATTLEPROD_TEST1 = CattleProd_LocaleString(CattleProd_COMMAND_CPTEST);
	SlashCmdList["CATTLEPROD_TEST"] = CattleProd_TestFunction;
end

--
-- Open configuration frame.
--
function CattleProd_Configure()
    CattleProd_ConfigurationFrame:Show();
end

--
-- Configure Frame OnLoad Event Handler.
--
-- Enable escape to close frame.
--
function CattleProd_ConfigurationFrameOnLoad()
    tinsert(UISpecialFrames,"CattleProd_ConfigurationFrame");
end

--
-- Main
--
function CattleProd_Main()
	CattleProd_Herd();
end

--
-- Manually calculate players states effort.
--
function CattleProd_Herd()
	CattleProd_Report(CattleProd_REPORT_LEVEL_HIGH, "Herding...");
	CattleProd_CalculatePlayersStatesEffort();
	CattleProd_Report(CattleProd_REPORT_LEVEL_HIGH, "... Herded");
end

--
-- Print the player's current location and defensive status.
--
function CattleProd_Defend()
	if (CattleProd_GetBattlegroundDefensiblePositionsMap_Function ~= nil)
	then
		local defensiblePositions = CattleProd_GetBattlegroundDefensiblePositionsMap_Function();
		if (defensiblePositions == nil)
		then
			CattleProd_Warn("Unable to get defensible positions");
			return;
		end
		
		local playerPositions = CattleProd_GetPlayerMapPositions();
		if (playerPositions == nil)
		then
			CattleProd_Warn("Unable to get player positions");
			return;
		end
	
		local playerX, playerY;
		playerX, playerY = GetPlayerMapPosition("player");
		
		local defender = CattleProd_IsDefender(defensiblePositions, { playerX * 100, playerY * 100 });
		if (defender == nil)
		then
			CattleProd_Warn("Unable to get defender status");
			return;
		end

		-- print whether player is defending	
		CattleProd_Message("Player Position: (%.2f, %.2f) Defending Status: %s", 
			playerX * 100, playerY * 100, tostring(defender));
	end
	
end

--
-- Test Function
--
function CattleProd_TestFunction()
	DEFAULT_CHAT_FRAME:AddMessage("CattleProd TestFunction");
end

--
-- Assert value is not null and of type.
--
-- value Value
-- dataType Data Type
-- ... Format Message
--
--
function CattleProd_AssertType(value, dataType, ...)
	if (value == nil)
	then
		CattleProd_Error("value == nil");
		error("value == nil", 2);
	end
	if (dataType == nil)
	then
		CattleProd_Error("dataType == nil");
		error("dataType == nil", 2);
	end

	if (type(value) ~= dataType)
	then
		-- message: passed in message
		local message = string.format(...) .. "\n";

		-- message: assert message
		message = message .. string.format("type(value) == %s: expected %s", type(value), dataType);

		CattleProd_Error(message);
		error(message, 2);
	end
end

--
-- Assert value not nil.
--
-- value Value
-- ... Format Message
--
function CattleProd_AssertNotNil(value, ...)
	if (value == nil)
	then
		-- message: passed in message
		local message = string.format(...) .. "\n";

		-- message: assert message
		message = message .. string.format("value == nil");

		CattleProd_Error(message);
		error(message, 2);
	end
end

--
-- Assert code is unreachable.
--
-- ... Format Message
--
function CattleProd_AssertUnreachable(...)
	-- message: passed in message
	local message = string.format(...) .. "\n";

	-- message: assert message
	message = message .. "Should Have Been Unreachable";

	CattleProd_Error(message);
	error(message, 2);
end

--
-- Print debug message.
--
-- ... Format Message
--
function CattleProd_Debug(...)
	if (DEFAULT_CHAT_FRAME)
	then
		-- message: passed in message
		local message = "DEBUG: " .. string.format(...);
--		DEFAULT_CHAT_FRAME:AddMessage(message);
	end
end

--
-- Print warn message.
--
-- ... Format Message
--
function CattleProd_Warn(...)
	if (DEFAULT_CHAT_FRAME)
	then
		-- message: passed in message
		local message = "WARN: " .. string.format(...);
		DEFAULT_CHAT_FRAME:AddMessage(message);
	end
end

--
-- Print error message.
--
-- ... Format Message
--
function CattleProd_Error(...)
	if (DEFAULT_CHAT_FRAME)
	then
		-- message: passed in message
		local message = "ERROR: " .. string.format(...);
		DEFAULT_CHAT_FRAME:AddMessage(message);
	end
end

--
-- Print CattleProd Message.
--
-- ... Format Message
--
function CattleProd_Message(...)
	if (DEFAULT_CHAT_FRAME)
	then
		DEFAULT_CHAT_FRAME:AddMessage(string.format(...));
	end	
end

--
-- Print CattleProd Report.
--
-- level Report Level
-- ... Format Message
--
function CattleProd_Report(level, ...)
	local reportLevel = CattleProd_GetSetting(CattleProd_REPORT_LEVEL);
	CattleProd_AssertType(reportLevel, "number", "Illegal State");
	if (level > reportLevel)
	then
		return;
	else
		CattleProd_Message(...);		
	end
end

--
-- Get faction.
--
-- return 0 = Horde, 1 = Alliance
--
function CattleProd_GetFaction()
	local faction = UnitFactionGroup("player");

	if (faction == CattleProd_FACTION_HORDE)
	then
		return 0;
	end
    
	if (faction == CattleProd_FACTION_ALLIANCE)
	then
		return 1;
	end

	CattleProd_AssertUnreachable("Unknown faction: %s", faction);
end

--
-- Array contains value.
--
-- array Array
-- value Value
--
-- return Boolean
--
function CattleProd_Contains(array, value)
	if (array == nil)
	then
		CattleProd_Error("CattleProd_Contains: array == nil");
		return nil;
	else
		if (type(array) ~= "table")
		then
			CattleProd_Error("CattleProd_Contains: type(array) ~= table");
			return nil;
		end
	end
	
	if (value == nil)
	then
		CattleProd_Error("CattleProd_Contains: value == nil");
		return nil;
	end
	
	for i, v in pairs(array)
	do
		if (v == value)
		then
			return true;
		end
	end
	
	return false;
end

--
-- Scale player damage and heal by the average damage and heal.
--
-- averageDamage Average Damage
-- averageHeal Average Heal
-- playerDamage Player Damage
-- playerHeal Player Heal
--
-- return Scaled Damage, Scaled Heal
--
function CattleProd_ScaleDamageAndHealing(averageDamage, averageHeal, playerDamage, playerHeal)
    local scaledDamage, scaledHeal
    
    if (averageDamage > averageHeal)
    then
        scaledDamage = playerDamage;
        scaledHeal = playerHeal * (averageDamage / averageHeal);
    else
        scaledDamage = playerDamage * (averageHeal / averageDamage);
        scaledHeal = playerHeal;
    end
    
    return scaledDamage, scaledHeal;
end

--
-- Print landmarks.
--
function CattleProd_PrintLandmarks()
	for landmark = 1, GetNumMapLandmarks()
	do
		local name, description, textureIndex, x, y
		name, description, textureIndex, x, y = GetMapLandmarkInfo(landmark);
		
		CattleProd_Message("%2d - name: %s description: %s textureIndex: %d xy: %2.1f,%2.1f",
			landmark, name, description, textureIndex, x * 100, y * 100);
	end
end

--
-- Check if player is a leech.
--
-- return true, false
--
function CattleProd_IsLeech(averageEffort, playerEffort)
	CattleProd_AssertType(averageEffort, "number", "Illegal Argument");
	CattleProd_AssertType(playerEffort, "number", "Illegal Argument");

	-- required effort
	local requiredEffortPercentage = CattleProd_GetSetting(
		CattleProd_REQUIRED_EFFORT_PERCENTAGE);

	if ((playerEffort / averageEffort) > requiredEffortPercentage)
	then
		return false
	else
		return true;
	end
end

--
-- ReportPlayerIsPVPAFK() wrapper.
--
-- playerKey Player Key
--
function CattleProd_ReportPlayerIsPVPAFK(playerKey)
	CattleProd_AssertType(playerKey, "string", "Illegal Argument");

	-- report players afk
	local reportPlayersAFK = CattleProd_GetSetting(CattleProd_REPORT_PLAYERS_AFK);
	if (not reportPlayersAFK)
	then
		return;
	end
	
	local localRealm = GetRealmName();
	local name, realm = CattleProd_PlayerNameRealm(playerKey);

	if (localRealm == realm)
	then
		ReportPlayerIsPVPAFK(name);
	else
		ReportPlayerIsPVPAFK(playerKey);
	end	
end

--
-- UnitIsGhost() wrapper.
--
-- playerKey Player key
--
function CattleProd_UnitIsGhost(playerKey)
	local localRealm = GetRealmName();
	local name, realm = CattleProd_PlayerNameRealm(playerKey);

	local ghost = false;

	if (localRealm == realm)
	then
		ghost = UnitIsGhost(name);
	else
		ghost = UnitIsGhost(playerKey);
	end	

	if (ghost == nil)
	then
		return false;
	else
		return true;
	end
end

--
-- Monitor Timer Key
--
CattleProd_MONITOR_TIMER_KEY = "monitor";

--
-- Check if monitor is started.
--
-- return Boolean
--
function CattleProd_MonitorStarted()
	return CattleProdTimer_IsListener(CattleProd_MONITOR_TIMER_KEY);
end

--
-- Start monitor.
--
function CattleProd_MonitorStart()
	if (not CattleProd_MonitorStarted())
	then
		local interval = CattleProd_GetSetting(CattleProd_MONITOR_DURATION);

		-- setup herd listener
		CattleProdTimer_AddListener(
			CattleProd_MONITOR_TIMER_KEY, interval, -1, CattleProd_Herd);
		CattleProd_MonitorFrame:SetScript("OnUpdate", CattleProd_MonitorFrame_OnUpdate);

		-- display monitor
		local displayMonitor = CattleProd_GetSetting(CattleProd_DISPLAY_MONITOR);
		if (displayMonitor)
		then
			-- set location
			local monitorPoint = CattleProd_GetSetting(CattleProd_MONITOR_POINT);
			
			CattleProd_MonitorFrame:ClearAllPoints();
			CattleProd_MonitorFrame:SetPoint(
				monitorPoint[1], getglobal("UIParent"), monitorPoint[2], monitorPoint[3], monitorPoint[4]);
	
			-- show monitor
			CattleProd_MonitorFrame:Show();
		end
	end
end

--
-- Stop monitor.
--
function CattleProd_MonitorStop()
	if (CattleProd_MonitorStarted())
	then
		-- display monitor
		local displayMonitor = CattleProd_GetSetting(CattleProd_DISPLAY_MONITOR);
		if (displayMonitor)
		then
			-- save location
			local point, relativeTo, relativePoint, xOfs, yOfs = CattleProd_MonitorFrame:GetPoint(1);
			local monitorPoint = { point, relativePoint, xOfs, yOfs };
			
			CattleProd_SetSetting(CattleProd_MONITOR_POINT, monitorPoint);
		end
		
		-- hide monitor
		CattleProd_MonitorFrame:Hide();
		
		-- clear timer
		CattleProdTimer_RemoveListener(CattleProd_MONITOR_TIMER_KEY);
	end
end

--
-- Toggle monitor.
--
function CattleProd_MonitorToggle()
	local started = CattleProd_MonitorStarted();

	if (started)
	then
		CattleProd_MonitorStop();
	else
		CattleProd_MonitorStart();
	end
end

--
-- Monitor Frame OnUpdate Event Handler.
--
function CattleProd_MonitorFrame_OnUpdate(self, elapsedTime)
	-- update afk
	local afkCount = # CattleProd_AFKPlayers;
	CattleProd_MonitorFrame_AFKFontString:SetFormattedText("%d AFKs", afkCount);

	-- update monitor
	local seconds = CattleProdTimer_GetSeconds(CattleProd_MONITOR_TIMER_KEY);
	CattleProd_MonitorFrame_MonitorFontString:SetFormattedText("%d Secs", seconds);
end

--
-- Constant: DEFAULT_SETTINGS_FLAG
--
CattleProd_DEFAULT_SETTINGS_FLAG = "DefaultSettings";

--
-- Constant: Report Players AFK
--
CattleProd_REPORT_PLAYERS_AFK = "ReportPlayersAFK";

--
-- Constant: Report Players AFK Default
--
CattleProd_REPORT_PLAYERS_AFK_DEFAULT = true;

--
-- Constant: Required Effort Percentage
--
CattleProd_REQUIRED_EFFORT_PERCENTAGE = "RequiredEffortPercentage";

--
-- Constant: Required Effort Percentage Default
--
CattleProd_REQUIRED_EFFORT_PERCENTAGE_DEFAULT = 0.10;

--
-- Constant: Report Known Leeches
--
CattleProd_REPORT_KNOWN_LEECHES = "ReportKnownLeeches";

--
-- Constant: Report Known Leeches Default
--
CattleProd_REPORT_KNOWN_LEECHES_DEFAULT = true;

--
-- Constant: Known Leech Count
--
CattleProd_KNOWN_LEECH_COUNT = "KnownLeechCount";

--
-- Constant: Known Leech Count Default
--
CattleProd_KNOWN_LEECH_COUNT_DEFAULT = 2;

--
-- Constant: Report Level
--
CattleProd_REPORT_LEVEL = "ReportLevel";

--
-- Constant: Report Level Default
--
CattleProd_REPORT_LEVEL_DEFAULT = CattleProd_REPORT_LEVEL_MEDIUM;

--
-- Constant: Announce Top N Leechers
--
CattleProd_ANNOUNCE_TOP_N_LEECHERS = "AnnounceTopNLeechers";

--
-- Constant: Announce Top N Leechers Default
--
CattleProd_ANNOUNCE_TOP_N_LEECHERS_DEFAULT = 3;

--
-- Constant: Calculate Player State Interval
--
CattleProd_CALCULATE_PLAYER_STATE_INTERVAL = "CalculatePlayerStateInterval";

--
-- Constant: Calculate Player State Interval Default (15 seconds)
--
CattleProd_CALCULATE_PLAYER_STATE_INTERVAL_DEFAULT = 15;

--
-- Constant: Required Data Points
--
CattleProd_REQUIRED_DATA_POINTS = "RequiredDataPoints";

--
-- Constant: Required Data Points Default (5 minutes)
--
CattleProd_REQUIRED_DATA_POINTS_DEFAULT = 300 / CattleProd_CALCULATE_PLAYER_STATE_INTERVAL_DEFAULT;

--
-- Constant: Display Monitor
--
CattleProd_DISPLAY_MONITOR = "DisplayMonitor";

--
-- Constant: Display Monitor Default
--
CattleProd_DISPLAY_MONITOR_DEFAULT = true;

--
-- Constant: Monitor Point
--
CattleProd_MONITOR_POINT = "MonitorPoint";

--
-- Constant: Monitor Point Default
--
CattleProd_MONITOR_POINT_DEFAULT = {"CENTER", "CENTER", 0, 300 };

--
-- Constant: Monitor Duration
--
CattleProd_MONITOR_DURATION = "MonitorDuration";

--
-- Constant: Monitor Duration
--
CattleProd_MONITOR_DURATION_DEFAULT = 180;

--
-- Constant: Auto Start Monitor
-- 
CattleProd_AUTO_START_MONITOR = "AutoStartMonitor";

--
-- Constant: Auto Start Monitor
--
CattleProd_AUTO_START_MONITOR_DEFAULT = true;

--
-- Constant: Alterac Valley Graveyard Assaulted Bonus Effort
--
CattleProd_ALTERAC_VALLEY_GRAVEYARD_ASSAULTED_BONUS_EFFORT = "AlteracValleyGraveyardAssaultedBonusEffort";

--
-- Constant: Alterac Valley Graveyard Assaulted Bonus Effort Default
--
CattleProd_ALTERAC_VALLEY_GRAVEYARD_ASSAULTED_BONUS_EFFORT_DEFAULT = 1000;

--
-- Constant: Alterac Valley Graveyard Defended Bonus Effort
--
CattleProd_ALTERAC_VALLEY_GRAVEYARD_DEFENDED_BONUS_EFFORT = "AlteracValleyGraveyardDefendedBonusEffort";

--
-- Constant: Alterac Valley Graveyard Defended Bonus Effort Default
--
CattleProd_ALTERAC_VALLEY_GRAVEYARD_DEFENDED_BONUS_EFFORT_DEFAULT = 1000;

--
-- Constant: Alterac Valley Tower Assaulted Bonus Effort
--
CattleProd_ALTERAC_VALLEY_TOWER_ASSAULTED_BONUS_EFFORT = "AlteracValleyTowerAssaultedBonusEffort";

--
-- Constant: Alterac Valley Tower Assaulted Bonus Effort Default
--
CattleProd_ALTERAC_VALLEY_TOWER_ASSAULTED_BONUS_EFFORT_DEFAULT = 1000;

--
-- Constant: Alterac Valley Tower Defended Bonus Effort
--
CattleProd_ALTERAC_VALLEY_TOWER_DEFENDED_BONUS_EFFORT = "AlteracValleyTowerDefendedBonusEffort";

--
-- Constant: Alterac Valley Tower Defended Bonus Effort Default
--
CattleProd_ALTERAC_VALLEY_TOWER_DEFENDED_BONUS_EFFORT_DEFAULT = 1000;

--
-- Constant: Alterac Valley Defender Bonus Effort
--
CattleProd_ALTERAC_VALLEY_DEFENDER_BONUS_EFFORT = "AlteracValleyDefenderBonusEffort";

--
-- Constant: Alterac Valley Defender Bonus Effort Default
--
CattleProd_ALTERAC_VALLEY_DEFENDER_BONUS_EFFORT_DEFAULT = 1000;

--
-- Constant: Arathi Basin Defender Bonus Effort
--
CattleProd_ARATHI_BASIN_DEFENDER_BONUS_EFFORT = "ArathiBasinDefenderBonusEffort";

--
-- Constant: Arathi Basin Defender Bonus Effort Default
--
CattleProd_ARATHI_BASIN_DEFENDER_BONUS_EFFORT_DEFAULT = 1000;

--
-- Constant: Arathi Basin Bases Assaulted Bonus Effort
--
CattleProd_ARATHI_BASIN_BASES_ASSAULTED_BONUS_EFFORT = "ArathiBasinBasesAssaultedBonusEffort";

--
-- Constant: Arathi Basin Bases Assaulted Bonus Effort Default
--
CattleProd_ARATHI_BASIN_BASES_ASSAULTED_BONUS_EFFORT_DEFAULT = 1000;

--
-- Constant: Arathi Basin Bases Defended Bonus Effort
--
CattleProd_ARATHI_BASIN_BASES_DEFENDED_BONUS_EFFORT = "ArathiBasinBassesDefendedBonusEffort";

--
-- Constant: Arathi Basin Bases Defended Bonus Effort Default
--
CattleProd_ARATHI_BASIN_BASES_DEFENDED_BONUS_EFFORT_DEFAULT = 1000;

--
-- Constant: Eye Of The Storm Defender Bonus Effort
--
CattleProd_EYE_OF_THE_STORM_DEFENDER_BONUS_EFFORT = "EyeOfTheStormDefenderBonusEffort";

--
-- Constant: Eye Of The Storm Bonus Effort Default
--
CattleProd_EYE_OF_THE_STORM_DEFENDER_BONUS_EFFORT_DEFAULT = 2000;
--
-- Constant: Eye Of The Storm Flags Captured Bonus Effort
--
CattleProd_EYE_OF_THE_STORM_FLAGS_CAPTURED_BONUS_EFFORT = "EyeOfTheStormFlagsCapturedBonusEffort";

--
-- Constant: Eye Of The Storm Flags Captured Bonus Effort Default
--
CattleProd_EYE_OF_THE_STORM_FLAGS_CAPTURED_BONUS_EFFORT_DEFAULT = 2000;

--
-- CattleProd_Settings
--
CattleProd_Settings = {};

--
-- Print Settings.
--
function CattleProd_PrintSettings()
	CattleProd_Message("CattleProd Settings:");

	for key, value in pairs(CattleProd_Settings)
	do
		CattleProd_Message("%s = %s", key, value);
	end
end

--
-- Set settings value.
--
-- setting Setting key
-- value Setting value
--
function CattleProd_SetSetting(setting, value)
	CattleProd_AssertNotNil(setting, "Illegal Argument");
	CattleProd_AssertNotNil(value, "Illegal Argument");

	-- mark as non-default
	CattleProd_Settings[CattleProd_DEFAULT_SETTINGS_FLAG] = false;
    
	-- update setting
	CattleProd_Settings[setting] = value;
end

--
-- Get setting value.
--
-- setting Setting key
--
-- return Settine value
--
function CattleProd_GetSetting(setting)
	CattleProd_AssertType(setting, "string", "Invalid Argument");
	
	local value = CattleProd_Settings[setting];
	if (value == nil)
	then
		CattleProd_LoadDefaultSettings();
		
		value = CattleProd_Settings[setting];
	end
	CattleProd_AssertNotNil(value, "Please Reload Default Settings: %s == nil", setting);

	return value;
end

--
-- Load default settings.
--
function CattleProd_LoadDefaultSettings()
	CattleProd_Message("CattleProd Loaded Default Settings");

	-- report players AFK
	CattleProd_SetSetting(
		CattleProd_REPORT_PLAYERS_AFK,
		CattleProd_REPORT_PLAYERS_AFK_DEFAULT);

	-- required effort
	CattleProd_SetSetting(
		CattleProd_REQUIRED_EFFORT_PERCENTAGE,
		CattleProd_REQUIRED_EFFORT_PERCENTAGE_DEFAULT);

	-- report known leeches
	CattleProd_SetSetting(
		CattleProd_REPORT_KNOWN_LEECHES,
		CattleProd_REPORT_KNOWN_LEECHES_DEFAULT);

	-- known leech count
	CattleProd_SetSetting(
		CattleProd_KNOWN_LEECH_COUNT,
		CattleProd_KNOWN_LEECH_COUNT_DEFAULT);

	-- report level
	CattleProd_SetSetting(
		CattleProd_REPORT_LEVEL,
		CattleProd_REPORT_LEVEL_DEFAULT);

	-- announce top n
	CattleProd_SetSetting(
		CattleProd_ANNOUNCE_TOP_N_LEECHERS,
		CattleProd_ANNOUNCE_TOP_N_LEECHERS_DEFAULT);

	-- calculate player state interval
	CattleProd_SetSetting(
		CattleProd_CALCULATE_PLAYER_STATE_INTERVAL,
		CattleProd_CALCULATE_PLAYER_STATE_INTERVAL_DEFAULT);

	-- required data points
	CattleProd_SetSetting(
		CattleProd_REQUIRED_DATA_POINTS,
		CattleProd_REQUIRED_DATA_POINTS_DEFAULT);

	-- display monitor
	CattleProd_SetSetting(
		CattleProd_DISPLAY_MONITOR,
		CattleProd_DISPLAY_MONITOR_DEFAULT);

	-- monitor point
	CattleProd_SetSetting(
		CattleProd_MONITOR_POINT,
		CattleProd_MONITOR_POINT_DEFAULT);

	-- monitor duration
	CattleProd_SetSetting(
		CattleProd_MONITOR_DURATION,
		CattleProd_MONITOR_DURATION_DEFAULT);

	-- auto start monitor
	CattleProd_SetSetting(
		CattleProd_AUTO_START_MONITOR,
		CattleProd_AUTO_START_MONITOR_DEFAULT);

	-- alterac valley graveyard assaulted bonus effort
	CattleProd_SetSetting(
		CattleProd_ALTERAC_VALLEY_GRAVEYARD_ASSAULTED_BONUS_EFFORT,
		CattleProd_ALTERAC_VALLEY_GRAVEYARD_ASSAULTED_BONUS_EFFORT_DEFAULT);

	-- alterac valley graveyard defended bonus effort
	CattleProd_SetSetting(
		CattleProd_ALTERAC_VALLEY_GRAVEYARD_DEFENDED_BONUS_EFFORT,
		CattleProd_ALTERAC_VALLEY_GRAVEYARD_DEFENDED_BONUS_EFFORT_DEFAULT);

	-- alterac valley tower assaulted bonus effort
	CattleProd_SetSetting(
		CattleProd_ALTERAC_VALLEY_TOWER_ASSAULTED_BONUS_EFFORT,
		CattleProd_ALTERAC_VALLEY_TOWER_ASSAULTED_BONUS_EFFORT_DEFAULT);

	-- alterac valley tower defended bonus effort
	CattleProd_SetSetting(
		CattleProd_ALTERAC_VALLEY_TOWER_DEFENDED_BONUS_EFFORT,
		CattleProd_ALTERAC_VALLEY_TOWER_DEFENDED_BONUS_EFFORT_DEFAULT);

	-- alterac valley defender bonus effort
	CattleProd_SetSetting(
		CattleProd_ALTERAC_VALLEY_DEFENDER_BONUS_EFFORT,
		CattleProd_ALTERAC_VALLEY_DEFENDER_BONUS_EFFORT_DEFAULT);

	-- arathi basin defender bonus effort
	CattleProd_SetSetting(
		CattleProd_ARATHI_BASIN_DEFENDER_BONUS_EFFORT,
		CattleProd_ARATHI_BASIN_DEFENDER_BONUS_EFFORT_DEFAULT);

	-- arathi basin bases assaulted bonus effort
	CattleProd_SetSetting(
		CattleProd_ARATHI_BASIN_BASES_ASSAULTED_BONUS_EFFORT,
		CattleProd_ARATHI_BASIN_BASES_ASSAULTED_BONUS_EFFORT_DEFAULT);

	-- arathi basin bases defended bonus effort
	CattleProd_SetSetting(
		CattleProd_ARATHI_BASIN_BASES_DEFENDED_BONUS_EFFORT,
		CattleProd_ARATHI_BASIN_BASES_DEFENDED_BONUS_EFFORT_DEFAULT);

	-- eye of the storm defender bonus effort
	CattleProd_SetSetting(
		CattleProd_EYE_OF_THE_STORM_DEFENDER_BONUS_EFFORT,
		CattleProd_EYE_OF_THE_STORM_DEFENDER_BONUS_EFFORT_DEFAULT);

	-- eye of the storm flags captured bonus effort
	CattleProd_SetSetting(
		CattleProd_EYE_OF_THE_STORM_FLAGS_CAPTURED_BONUS_EFFORT,
		CattleProd_EYE_OF_THE_STORM_FLAGS_CAPTURED_BONUS_EFFORT_DEFAULT);

	-- default settings
	CattleProd_Settings[CattleProd_DEFAULT_SETTINGS_FLAG] = true;
end

--
-- Report Players AFK Check Button OnShow Event Handler
--
function CattleProd_ReportPlayersAFKCheckButtonOnShow()
	-- initialize check button
	local reportPlayersAFK = CattleProd_GetSetting(
		CattleProd_REPORT_PLAYERS_AFK);

	CattleProd_ReportPlayersAFKCheckButton:SetChecked(reportPlayersAFK);
end

--
-- Report Players AFK Check Button OnClick Event Handler
--
function CattleProd_ReportPlayersAFKCheckButtonOnClick()
	-- update report players afk setting
	local reportPlayersAFK = CattleProd_ReportPlayersAFKCheckButton:GetChecked();

	if (reportPlayersAFK)
	then
		reportPlayersAFK = true;
	else
		reportPlayersAFK = false;
	end
    
	CattleProd_SetSetting(CattleProd_REPORT_PLAYERS_AFK, reportPlayersAFK);
end

--
-- Required Effort Slider OnShow Event Handler.
--
function CattleProd_RequiredEffortSliderOnShow()
	-- initialize slider
	CattleProd_RequiredEffortSliderHigh:SetText("1.00%");
	CattleProd_RequiredEffortSliderLow:SetText("0.00%");
	CattleProd_RequiredEffortSlider:SetMinMaxValues(0.00, 1.00);
	CattleProd_RequiredEffortSlider:SetValueStep(0.01);

	local requiredEffort = CattleProd_GetSetting(
		CattleProd_REQUIRED_EFFORT_PERCENTAGE);

	CattleProd_RequiredEffortSlider:SetValue(requiredEffort);
	CattleProd_RequiredEffortSliderText:SetFormattedText(
		"Required Effort: %d%%", (requiredEffort * 100));
end

--
-- Required Effort Slider OnValueChanged Event Handler.
--
function CattleProd_RequiredEffortSliderOnValueChanged()
	-- update required effort slider
	local requiredEffort = CattleProd_RequiredEffortSlider:GetValue();
	local requiredEffortString = string.format("%.2f", requiredEffort);

	requiredEffort = tonumber(requiredEffortString);

	CattleProd_RequiredEffortSliderText:SetFormattedText(
		"Required Effort: %d%%", (requiredEffort * 100));

	CattleProd_SetSetting(
		CattleProd_REQUIRED_EFFORT_PERCENTAGE, requiredEffort);
end

--
-- Report Known Leeches Check Button OnShow Event Handler
--
function CattleProd_ReportKnownLeechesButtonOnShow()
	-- initialize check button
	local reportKnownLeeches = CattleProd_GetSetting(
		CattleProd_REPORT_KNOWN_LEECHES);

	CattleProd_ReportKnownLeechesButton:SetChecked(reportKnownLeeches);
end

--
-- Report Known Leeches Check Button OnClick Event Handler
--
function CattleProd_ReportKnownLeechesButtonOnClick()
	-- update report players afk setting
	local reportKnownLeeches = CattleProd_ReportKnownLeechesButton:GetChecked();

	if (reportKnownLeeches)
	then
		reportKnownLeeches = true;
	else
		reportKnownLeeches = false;
	end
    
	CattleProd_SetSetting(CattleProd_REPORT_KNOWN_LEECHES, reportKnownLeeches);
end

--
-- Known Leech Count OnShow Event Handler.
--
function CattleProd_KnownLeechCountSliderOnShow()
	-- initialize slider
	CattleProd_KnownLeechCountSliderHigh:SetText("10");
	CattleProd_KnownLeechCountSliderLow:SetText("1");
	CattleProd_KnownLeechCountSlider:SetMinMaxValues(1, 10);
	CattleProd_KnownLeechCountSlider:SetValueStep(1);

	local knownLeechCount = CattleProd_GetSetting(
		CattleProd_KNOWN_LEECH_COUNT);

	CattleProd_KnownLeechCountSlider:SetValue(knownLeechCount);
	CattleProd_KnownLeechCountSliderText:SetFormattedText(
		"Known Leech Count: %d", knownLeechCount);
end

--
-- Known Leech Count Slider OnValueChanged Event Handler.
--
function CattleProd_KnownLeechCountSliderOnValueChanged()
	-- update required effort slider
	local knownLeechCount = CattleProd_KnownLeechCountSlider:GetValue();
	local knownLeechCountString = string.format("%d", knownLeechCount);

	knownLeechCount = tonumber(knownLeechCountString);

	CattleProd_KnownLeechCountSliderText:SetFormattedText(
		"Known Leech Count: %d", knownLeechCount);

	CattleProd_SetSetting(
		CattleProd_KNOWN_LEECH_COUNT, knownLeechCount);
end

--
-- Report Level Slider OnShow Event Handler.
--
function CattleProd_ReportLevelSliderOnShow()
	-- initialize slider
	CattleProd_ReportLevelSliderHigh:SetText("None");
	CattleProd_ReportLevelSliderLow:SetText("High");
	CattleProd_ReportLevelSlider:SetMinMaxValues(0, 3);
	CattleProd_ReportLevelSlider:SetValueStep(1);

	local reportLevel = CattleProd_GetSetting(
		CattleProd_REPORT_LEVEL);

	CattleProd_ReportLevelSlider:SetValue(reportLevel);
	CattleProd_ReportLevelSliderText:SetFormattedText(
		"Report Level: %d", reportLevel);
end

--
-- Report Level Slider OnValueChanged Event Handler.
--
function CattleProd_ReportLevelOnValueChanged()
	-- update slider
	local reportLevel = CattleProd_ReportLevelSlider:GetValue();
	local reportLevelString = string.format("%d", reportLevel);

	reportLevel = tonumber(reportLevelString);

	CattleProd_ReportLevelSliderText:SetFormattedText(
		"Report Level: %d", reportLevel);

	CattleProd_SetSetting(
		CattleProd_REPORT_LEVEL, reportLevel);
end

--
-- Announce Top N Leechers Slider OnShow Event Handler.
--
function CattleProd_AnnounceTopNLeechersSliderOnShow()
	-- initialize slider
	CattleProd_AnnounceTopNLeechersSliderHigh:SetText("10");
	CattleProd_AnnounceTopNLeechersSliderLow:SetText("1");
	CattleProd_AnnounceTopNLeechersSlider:SetMinMaxValues(1, 10);
	CattleProd_AnnounceTopNLeechersSlider:SetValueStep(1);

	local announceTopNLeechers = CattleProd_GetSetting(
		CattleProd_ANNOUNCE_TOP_N_LEECHERS);

	CattleProd_AnnounceTopNLeechersSlider:SetValue(announceTopNLeechers);
	CattleProd_AnnounceTopNLeechersSliderText:SetFormattedText(
		"Announce Top %d Leechers", announceTopNLeechers);
end

--
-- Announce Top N Leechers Slider OnValueChanged Event Handler.
--
function CattleProd_AnnounceTopNLeechersSliderOnValueChanged()
	-- update required effort slider
	local announceTopNLeechers = CattleProd_AnnounceTopNLeechersSlider:GetValue();
	local announceTopNLeechersString = string.format("%d", announceTopNLeechers);

	announceTopNLeechers = tonumber(announceTopNLeechersString);

	CattleProd_AnnounceTopNLeechersSliderText:SetFormattedText(
		"Announce Top %d Leechers", announceTopNLeechers);

	CattleProd_SetSetting(
		CattleProd_ANNOUNCE_TOP_N_LEECHERS, announceTopNLeechers);
end

--
-- Auto Start Monitor CheckButton OnShow Event Handler.
--
function CattleProd_AutoStartMonitorCheckButtonOnShow()
	-- initialize check button
	local autoStartMonitor = CattleProd_GetSetting(
		CattleProd_AUTO_START_MONITOR);

	CattleProd_AutoStartMonitorCheckButton:SetChecked(autoStartMonitor);
end

--
-- Auto Start Monitor CheckButton OnClick Event Handler
--
function CattleProd_AutoStartMonitorCheckButtonOnClick()
	-- update setting
	local autoStartMonitor =
		CattleProd_AutoStartMonitorCheckButton:GetChecked();

	if (autoStartMonitor)
	then
		autoStartMonitor = true;
	else
		autoStartMonitor = false;
	end
    
	CattleProd_SetSetting(CattleProd_AUTO_START_MONITOR, autoStartMonitor);
end

--
-- Monitor Duration Slider OnShow Event Handler.
--
function CattleProd_MonitorDurationSliderOnShow()
	-- initialize slider
	CattleProd_MonitorDurationSliderHigh:SetText("600 Sec");
	CattleProd_MonitorDurationSliderLow:SetText("60 Sec");
	CattleProd_MonitorDurationSlider:SetMinMaxValues(60, 600);
	CattleProd_MonitorDurationSlider:SetValueStep(30);

	local monitorDuration = CattleProd_GetSetting(
		CattleProd_MONITOR_DURATION);

	CattleProd_MonitorDurationSlider:SetValue(monitorDuration);
	CattleProd_MonitorDurationSliderText:SetFormattedText(
		"Monitor Duration: %d Sec", monitorDuration);
end

--
-- Monitor Duration Slider OnValueChanged Event Handler.
--
function CattleProd_MonitorDurationSliderOnValueChanged()
	-- update monitor duration
	local monitorDuration = CattleProd_MonitorDurationSlider:GetValue();
	local monitorDurationString = string.format("%d", monitorDuration);

	monitorDuration = tonumber(monitorDurationString);

	CattleProd_MonitorDurationSliderText:SetFormattedText(
		"Monitor Duration: %d Sec", monitorDuration);

	CattleProd_SetSetting(CattleProd_MONITOR_DURATION, monitorDuration);
end

--
-- Player State Interval Slider OnShow Event Handler.
--
function CattleProd_PlayerStateIntervalSliderOnShow()
	-- initialize slider
	CattleProd_PlayerStateIntervalSliderLow:SetText("10 Sec");
	CattleProd_PlayerStateIntervalSliderHigh:SetText("60 Sec");
	CattleProd_PlayerStateIntervalSlider:SetMinMaxValues(10, 60);
	CattleProd_PlayerStateIntervalSlider:SetValueStep(1);

	local playerStateInterval = CattleProd_GetSetting(
		CattleProd_CALCULATE_PLAYER_STATE_INTERVAL);

	CattleProd_PlayerStateIntervalSlider:SetValue(playerStateInterval);
	CattleProd_PlayerStateIntervalSliderText:SetFormattedText(
		"Player State Interval: %d Sec", playerStateInterval);
end

--
-- Player State Interval Slider OnValueChanged Event Handler.
--
function CattleProd_PlayerStateIntervalSliderOnValueChanged()
	-- update monitor duration
	local playerStateInterval = CattleProd_PlayerStateIntervalSlider:GetValue();
	local playerStateIntervalString = string.format("%d", playerStateInterval);

	playerStateInterval = tonumber(playerStateIntervalString);

	CattleProd_PlayerStateIntervalSliderText:SetFormattedText(
		"Player State Interval: %d Sec", playerStateInterval);

	CattleProd_SetSetting(CattleProd_CALCULATE_PLAYER_STATE_INTERVAL, playerStateInterval);
end

--
-- Required Data Points Slider OnShow Event Handler.
--
function CattleProd_RequiredDataPointsSliderOnShow()
	-- initialize slider
	CattleProd_RequiredDataPointsSliderLow:SetText("10");
	CattleProd_RequiredDataPointsSliderHigh:SetText("40");
	CattleProd_RequiredDataPointsSlider:SetMinMaxValues(10, 40);
	CattleProd_RequiredDataPointsSlider:SetValueStep(1);

	local requiredDataPoints = CattleProd_GetSetting(
		CattleProd_REQUIRED_DATA_POINTS);

	CattleProd_RequiredDataPointsSlider:SetValue(requiredDataPoints);
	CattleProd_RequiredDataPointsSliderText:SetFormattedText(
		"Required Data Points: %d", requiredDataPoints);
end

--
-- Required Data Points Slider OnValueChanged Event Handler.
--
function CattleProd_RequiredDataPointsSliderOnValueChanged()
	-- update monitor duration
	local requiredDataPoints = CattleProd_RequiredDataPointsSlider:GetValue();
	local requiredDataPointsString = string.format("%d", requiredDataPoints);

	requiredDataPoints = tonumber(requiredDataPointsString);

	CattleProd_RequiredDataPointsSliderText:SetFormattedText(
		"Required Data Points: %d", requiredDataPoints);

	CattleProd_SetSetting(CattleProd_REQUIRED_DATA_POINTS, requiredDataPoints);
end


--
-- Display Monitor OnShow Event Handler
--
function CattleProd_DisplayMonitorCheckButtonOnShow()
	-- initialize check button
	local displayMonitor = CattleProd_GetSetting(
		CattleProd_DISPLAY_MONITOR);

	CattleProd_DisplayMonitorCheckButton:SetChecked(displayMonitor);
end

--
-- Display Monitor Check Button OnClick Event Handler
--
function CattleProd_DisplayMonitorCheckButtonOnClick()
	-- update report players afk setting
	local displayMonitor = CattleProd_DisplayMonitorCheckButton:GetChecked();

	if (displayMonitor)
	then
		displayMonitor = true;
	else
		displayMonitor = false;
	end

	-- update monitor display
	if (CattleProd_MonitorStarted())
	then
		if (displayMonitor)
		then
			CattleProd_MonitorFrame:Show();
		else
			CattleProd_MonitorFrame:Hide();
		end
	end
    
	CattleProd_SetSetting(CattleProd_DISPLAY_MONITOR, displayMonitor);
end

--
-- Alterac Valley Graveyard Assulted Slider OnShow Event Handler.
--
function CattleProd_AlteracValleyGraveyardAssaultedSliderOnShow()
	-- initialize slider
	CattleProd_AlteracValleyGraveyardAssaultedSliderHigh:SetText("2000");
	CattleProd_AlteracValleyGraveyardAssaultedSliderLow:SetText("100");
	CattleProd_AlteracValleyGraveyardAssaultedSlider:SetMinMaxValues(100, 2000);
	CattleProd_AlteracValleyGraveyardAssaultedSlider:SetValueStep(25);

	local bonusEffort = CattleProd_GetSetting(
		CattleProd_ALTERAC_VALLEY_GRAVEYARD_ASSAULTED_BONUS_EFFORT);

	CattleProd_AlteracValleyGraveyardAssaultedSlider:SetValue(bonusEffort);
	CattleProd_AlteracValleyGraveyardAssaultedSliderText:SetFormattedText(
		"Graveyard Assaulted Bonus Effort: %d", bonusEffort);
end

--
-- Alterac Valley Graveyard Assaulted Slider OnValueChanged Event Handler.
--
function CattleProd_AlteracValleyGraveyardAssaultedSliderOnValueChanged()
	-- update
	local bonusEffort = CattleProd_AlteracValleyGraveyardAssaultedSlider:GetValue();
	local bonusEffortString = string.format("%d", bonusEffort);

	bonusEffort = tonumber(bonusEffortString);

	CattleProd_AlteracValleyGraveyardAssaultedSliderText:SetFormattedText(
		"Graveyard Assaulted Bonus Effort: %d", bonusEffort);

	CattleProd_SetSetting(CattleProd_ALTERAC_VALLEY_GRAVEYARD_ASSAULTED_BONUS_EFFORT, bonusEffort);
end

--
-- Alterac Valley Graveyard Defended Slider OnShow Event Handler.
--
function CattleProd_AlteracValleyGraveyardDefendedSliderOnShow()
	-- initialize slider
	CattleProd_AlteracValleyGraveyardDefendedSliderHigh:SetText("2000");
	CattleProd_AlteracValleyGraveyardDefendedSliderLow:SetText("100");
	CattleProd_AlteracValleyGraveyardDefendedSlider:SetMinMaxValues(100, 2000);
	CattleProd_AlteracValleyGraveyardDefendedSlider:SetValueStep(25);

	local bonusEffort = CattleProd_GetSetting(
		CattleProd_ALTERAC_VALLEY_GRAVEYARD_DEFENDED_BONUS_EFFORT);

	CattleProd_AlteracValleyGraveyardDefendedSlider:SetValue(bonusEffort);
	CattleProd_AlteracValleyGraveyardDefendedSliderText:SetFormattedText(
		"Graveyard Defended Bonus Effort: %d", bonusEffort);
end

--
-- Alterac Valley Graveyard Defended Slider OnValueChanged Event Handler.
--
function CattleProd_AlteracValleyGraveyardDefendedSliderOnValueChanged()
	-- update
	local bonusEffort = CattleProd_AlteracValleyGraveyardDefendedSlider:GetValue();
	local bonusEffortString = string.format("%d", bonusEffort);

	bonusEffort = tonumber(bonusEffortString);

	CattleProd_AlteracValleyGraveyardDefendedSliderText:SetFormattedText(
		"Graveyard Defended Bonus Effort: %d", bonusEffort);

	CattleProd_SetSetting(CattleProd_ALTERAC_VALLEY_GRAVEYARD_DEFENDED_BONUS_EFFORT, bonusEffort);
end

--
-- Alterac Valley Tower Assulted Slider OnShow Event Handler.
--
function CattleProd_AlteracValleyTowerAssaultedSliderOnShow()
	-- initialize slider
	CattleProd_AlteracValleyTowerAssaultedSliderHigh:SetText("2000");
	CattleProd_AlteracValleyTowerAssaultedSliderLow:SetText("100");
	CattleProd_AlteracValleyTowerAssaultedSlider:SetMinMaxValues(100, 2000);
	CattleProd_AlteracValleyTowerAssaultedSlider:SetValueStep(25);

	local bonusEffort = CattleProd_GetSetting(
		CattleProd_ALTERAC_VALLEY_TOWER_ASSAULTED_BONUS_EFFORT);

	CattleProd_AlteracValleyTowerAssaultedSlider:SetValue(bonusEffort);
	CattleProd_AlteracValleyTowerAssaultedSliderText:SetFormattedText(
		"Tower Assaulted Bonus Effort: %d", bonusEffort);
end

--
-- Alterac Valley Tower Assaulted Slider OnValueChanged Event Handler.
--
function CattleProd_AlteracValleyTowerAssaultedSliderOnValueChanged()
	-- update
	local bonusEffort = CattleProd_AlteracValleyTowerAssaultedSlider:GetValue();
	local bonusEffortString = string.format("%d", bonusEffort);

	bonusEffort = tonumber(bonusEffortString);

	CattleProd_AlteracValleyTowerAssaultedSliderText:SetFormattedText(
		"Tower Assaulted Bonus Effort: %d", bonusEffort);

	CattleProd_SetSetting(CattleProd_ALTERAC_VALLEY_TOWER_ASSAULTED_BONUS_EFFORT, bonusEffort);
end

--
-- Alterac Valley Tower Defended Slider OnShow Event Handler.
--
function CattleProd_AlteracValleyTowerDefendedSliderOnShow()
	-- initialize slider
	CattleProd_AlteracValleyTowerDefendedSliderHigh:SetText("2000");
	CattleProd_AlteracValleyTowerDefendedSliderLow:SetText("100");
	CattleProd_AlteracValleyTowerDefendedSlider:SetMinMaxValues(100, 2000);
	CattleProd_AlteracValleyTowerDefendedSlider:SetValueStep(25);

	local bonusEffort = CattleProd_GetSetting(
		CattleProd_ALTERAC_VALLEY_TOWER_DEFENDED_BONUS_EFFORT);

	CattleProd_AlteracValleyTowerDefendedSlider:SetValue(bonusEffort);
	CattleProd_AlteracValleyTowerDefendedSliderText:SetFormattedText(
		"Tower Defended Bonus Effort: %d", bonusEffort);
end

--
-- Alterac Valley Tower Defended Slider OnValueChanged Event Handler.
--
function CattleProd_AlteracValleyTowerDefendedSliderOnValueChanged()
	-- update
	local bonusEffort = CattleProd_AlteracValleyTowerDefendedSlider:GetValue();
	local bonusEffortString = string.format("%d", bonusEffort);

	bonusEffort = tonumber(bonusEffortString);

	CattleProd_AlteracValleyTowerDefendedSliderText:SetFormattedText(
		"Tower Defended Bonus Effort: %d", bonusEffort);

	CattleProd_SetSetting(CattleProd_ALTERAC_VALLEY_TOWER_DEFENDED_BONUS_EFFORT, bonusEffort);
end

--
-- Alterac Valley Defender Effort Slider OnShow Event Handler.
--
function CattleProd_AlteracValleyDefenderEffortSliderOnShow()
	-- initialize slider
	CattleProd_AlteracValleyDefenderEffortSliderHigh:SetText("2000");
	CattleProd_AlteracValleyDefenderEffortSliderLow:SetText("100");
	CattleProd_AlteracValleyDefenderEffortSlider:SetMinMaxValues(100, 2000);
	CattleProd_AlteracValleyDefenderEffortSlider:SetValueStep(25);

	local bonusEffort = CattleProd_GetSetting(
		CattleProd_ALTERAC_VALLEY_DEFENDER_BONUS_EFFORT);

	CattleProd_AlteracValleyDefenderEffortSlider:SetValue(bonusEffort);
	CattleProd_AlteracValleyDefenderEffortSliderText:SetFormattedText(
		"Defender Bonus Effort: %d", bonusEffort);
end

--
-- Alterac Valley Defender Effort Slider OnValueChanged Event Handler.
--
function CattleProd_AlteracValleyDefenderEffortSliderOnValueChanged()
	-- update
	local bonusEffort = CattleProd_AlteracValleyDefenderEffortSlider:GetValue();
	local bonusEffortString = string.format("%d", bonusEffort);

	bonusEffort = tonumber(bonusEffortString);

	CattleProd_AlteracValleyDefenderEffortSliderText:SetFormattedText(
		"Defender Bonus Effort: %d", bonusEffort);

	CattleProd_SetSetting(CattleProd_ALTERAC_VALLEY_DEFENDER_BONUS_EFFORT, bonusEffort);
end

--
-- Arathi Basin Defender Bonus Effort Slider OnShow Event Handler.
--
function CattleProd_ArathiBasinDefenderBonusEffortSliderOnShow()
	-- initialize slider
	CattleProd_ArathiBasinDefenderBonusEffortSliderLow:SetText("100");
	CattleProd_ArathiBasinDefenderBonusEffortSliderHigh:SetText("2000");
	CattleProd_ArathiBasinDefenderBonusEffortSlider:SetMinMaxValues(100, 2000);
	CattleProd_ArathiBasinDefenderBonusEffortSlider:SetValueStep(25);

	local bonusEffort = CattleProd_GetSetting(
		CattleProd_ARATHI_BASIN_DEFENDER_BONUS_EFFORT);

	CattleProd_ArathiBasinDefenderBonusEffortSlider:SetValue(bonusEffort);
	CattleProd_ArathiBasinDefenderBonusEffortSliderText:SetFormattedText(
		"Defender Bonus Effort: %d", bonusEffort);
end

--
-- Arathi Basin Defender Bonus Effort Slider OnValueChanged Event Handler.
--
function CattleProd_ArathiBasinDefenderBonusEffortSliderOnValueChanged()
	-- update
	local bonusEffort = CattleProd_ArathiBasinDefenderBonusEffortSlider:GetValue();
	local bonusEffortString = string.format("%d", bonusEffort);

	bonusEffort = tonumber(bonusEffortString);

	CattleProd_ArathiBasinDefenderBonusEffortSliderText:SetFormattedText(
		"Defender Bonus Effort: %d", bonusEffort);

	CattleProd_SetSetting(CattleProd_ARATHI_BASIN_DEFENDER_BONUS_EFFORT, bonusEffort);
end

--
-- Arathi Basin Bases Assaulted Bonus Effort Slider OnShow Event Handler.
--
function CattleProd_ArathiBasinBasesAssaultedBonusEffortSliderOnShow()
	-- initialize slider
	CattleProd_ArathiBasinBasesAssaultedBonusEffortSliderLow:SetText("100");
	CattleProd_ArathiBasinBasesAssaultedBonusEffortSliderHigh:SetText("2000");
	CattleProd_ArathiBasinBasesAssaultedBonusEffortSlider:SetMinMaxValues(100, 2000);
	CattleProd_ArathiBasinBasesAssaultedBonusEffortSlider:SetValueStep(25);

	local bonusEffort = CattleProd_GetSetting(
		CattleProd_ARATHI_BASIN_BASES_ASSAULTED_BONUS_EFFORT);

	CattleProd_ArathiBasinBasesAssaultedBonusEffortSlider:SetValue(bonusEffort);
	CattleProd_ArathiBasinBasesAssaultedBonusEffortSliderText:SetFormattedText(
		"Bases Assaulted Bonus Effort: %d", bonusEffort);
end

--
-- Arathi Basin Bases Assaulted Bonus Effort Slider OnValueChanged Event Handler.
--
function CattleProd_ArathiBasinBasesAssaultedBonusEffortSliderOnValueChanged()
	-- update
	local bonusEffort = CattleProd_ArathiBasinBasesAssaultedBonusEffortSlider:GetValue();
	local bonusEffortString = string.format("%d", bonusEffort);

	bonusEffort = tonumber(bonusEffortString);

	CattleProd_ArathiBasinBasesAssaultedBonusEffortSliderText:SetFormattedText(
		"Bases Assaulted Bonus Effort: %d", bonusEffort);

	CattleProd_SetSetting(CattleProd_ARATHI_BASIN_BASES_ASSAULTED_BONUS_EFFORT, bonusEffort);
end

--
-- Arathi Basin Bases Defended Bonus Effort Slider OnShow Event Handler.
--
function CattleProd_ArathiBasinBasesDefendedBonusEffortSliderOnShow()
	-- initialize slider
	CattleProd_ArathiBasinBasesDefendedBonusEffortSliderLow:SetText("100");
	CattleProd_ArathiBasinBasesDefendedBonusEffortSliderHigh:SetText("2000");
	CattleProd_ArathiBasinBasesDefendedBonusEffortSlider:SetMinMaxValues(100, 2000);
	CattleProd_ArathiBasinBasesDefendedBonusEffortSlider:SetValueStep(25);

	local bonusEffort = CattleProd_GetSetting(
		CattleProd_ARATHI_BASIN_BASES_DEFENDED_BONUS_EFFORT);

	CattleProd_ArathiBasinBasesDefendedBonusEffortSlider:SetValue(bonusEffort);
	CattleProd_ArathiBasinBasesDefendedBonusEffortSliderText:SetFormattedText(
		"Bases Defended Bonus Effort: %d", bonusEffort);
end

--
-- Arathi Basin Bases Defended Bonus Effort Slider OnValueChanged Event Handler.
--
function CattleProd_ArathiBasinBasesDefendedBonusEffortSliderOnValueChanged()
	-- update
	local bonusEffort = CattleProd_ArathiBasinBasesDefendedBonusEffortSlider:GetValue();
	local bonusEffortString = string.format("%d", bonusEffort);

	bonusEffort = tonumber(bonusEffortString);

	CattleProd_ArathiBasinBasesDefendedBonusEffortSliderText:SetFormattedText(
		"Defender Bonus Effort: %d", bonusEffort);

	CattleProd_SetSetting(CattleProd_ARATHI_BASIN_BASES_DEFENDED_BONUS_EFFORT, bonusEffort);
end

--
-- Eye Of The Storm Defender Bonus Effort Slider OnShow Event Handler.
--
function CattleProd_EyeOfTheStormDefenderBonusEffortSliderOnShow()
	-- initialize slider
	CattleProd_EyeOfTheStormDefenderBonusEffortSliderLow:SetText("100");
	CattleProd_EyeOfTheStormDefenderBonusEffortSliderHigh:SetText("4000");
	CattleProd_EyeOfTheStormDefenderBonusEffortSlider:SetMinMaxValues(100, 4000);
	CattleProd_EyeOfTheStormDefenderBonusEffortSlider:SetValueStep(100);

	local bonusEffort = CattleProd_GetSetting(
		CattleProd_EYE_OF_THE_STORM_DEFENDER_BONUS_EFFORT);

	CattleProd_EyeOfTheStormDefenderBonusEffortSlider:SetValue(bonusEffort);
	CattleProd_EyeOfTheStormDefenderBonusEffortSliderText:SetFormattedText(
		"Defender Bonus Effort: %d", bonusEffort);
end

--
-- Eye Of The Storm Defender Bonus Effort Slider OnValueChanged Event Handler.
--
function CattleProd_EyeOfTheStormDefenderBonusEffortSliderOnValueChanged()
	-- update
	local bonusEffort = CattleProd_EyeOfTheStormDefenderBonusEffortSlider:GetValue();
	local bonusEffortString = string.format("%d", bonusEffort);

	bonusEffort = tonumber(bonusEffortString);

	CattleProd_EyeOfTheStormDefenderBonusEffortSliderText:SetFormattedText(
		"Defender Bonus Effort: %d", bonusEffort);

	CattleProd_SetSetting(CattleProd_EYE_OF_THE_STORM_DEFENDER_BONUS_EFFORT, bonusEffort);
end

--
-- Eye Of The Storm Flags Captured Bonus Effort Slider OnShow Event Handler.
--
function CattleProd_EyeOfTheStormFlagsCapturedBonusEffortSliderOnShow()
	-- initialize slider
	CattleProd_EyeOfTheStormFlagsCapturedBonusEffortSliderLow:SetText("100");
	CattleProd_EyeOfTheStormFlagsCapturedBonusEffortSliderHigh:SetText("4000");
	CattleProd_EyeOfTheStormFlagsCapturedBonusEffortSlider:SetMinMaxValues(100, 4000);
	CattleProd_EyeOfTheStormFlagsCapturedBonusEffortSlider:SetValueStep(100);

	local bonusEffort = CattleProd_GetSetting(
		CattleProd_EYE_OF_THE_STORM_FLAGS_CAPTURED_BONUS_EFFORT);

	CattleProd_EyeOfTheStormFlagsCapturedBonusEffortSlider:SetValue(bonusEffort);
	CattleProd_EyeOfTheStormFlagsCapturedBonusEffortSliderText:SetFormattedText(
		"Flags Captured Bonus Effort: %d", bonusEffort);
end

--
-- Eye Of The Storm Flags Captured Bonus Effort Slider OnValueChanged Event Handler.
--
function CattleProd_EyeOfTheStormFlagsCapturedBonusEffortSliderOnValueChanged()
	-- update
	local bonusEffort = CattleProd_EyeOfTheStormFlagsCapturedBonusEffortSlider:GetValue();
	local bonusEffortString = string.format("%d", bonusEffort);

	bonusEffort = tonumber(bonusEffortString);

	CattleProd_EyeOfTheStormFlagsCapturedBonusEffortSliderText:SetFormattedText(
		"Flags Captured Bonus Effort: %d", bonusEffort);

	CattleProd_SetSetting(CattleProd_EYE_OF_THE_STORM_FLAGS_CAPTURED_BONUS_EFFORT, bonusEffort);
end
